#ifndef _DriverBootloader_H_
#define _DriverBootloader_H_


#include "DevicesFlash.h"


/* size: 16k Byte */
#define FLASH_BOOT_ADDR             (FLASH_BASE_ADDR + 1024 * (0))
/* size: 4k Byte */
#define FLASH_SYSTEM_DATA_ADDR      (FLASH_BASE_ADDR + 1024 * (16))
/* size: 4k Byte */
#define FLASH_OTA_DATA_ADDR         (FLASH_BASE_ADDR + 1024 * (16 + 2))
/* size: 2k Byte */
#define FLASH_USER_DATA_ADDR        (FLASH_BASE_ADDR + 1024 * (16 + 4))
/* size: 2k Byte */
#define FLASH_USER_DATA_BACK_ADDR   (FLASH_BASE_ADDR + 1024 * (16 + 4 + 2))
/* size: 64k Byte */
#define FLASH_BOOTLOADER_ADDR       (FLASH_BASE_ADDR + 1024 * (16 + 4 + 2 + 2))
/* size: 64k Byte */
#define FLASH_BOOTLOADER_BACK_ADDR  (FLASH_BASE_ADDR + 1024 * (16 + 4 + 4 + 64))
/* size: 剩余的空间 */
#define FLASH_APP_ADDR              (FLASH_BASE_ADDR + 1024 * (16 + 4 + 4 + 64 + 64))


#define FIRMWARE_CHANNEL_BOOTLOADER                 0x01
#define FIRMWARE_CHANNEL_BOOTLOADER_BACK_INSIDE     0x02
#define FIRMWARE_CHANNEL_BOOTLOADER_BACK_OUTSIDE    0x04
#define FIRMWARE_CHANNEL_APP                        0x10
#define FIRMWARE_CHANNEL_APP_BACK_INSIDE            0x20
#define FIRMWARE_CHANNEL_APP_BACK_OUTSIDE           0x40


/* 来源内部Flash */
#define FIRMWARE_SOURCE_ROM       0x00
/* 来源外部SPI Flash */
#define FIRMWARE_SOURCE_SPI_FLASH 0x01
/* 是否需要更新 */
#define FIRMWARE_UPDATE           0x04
/* 未开启CRC校验 */
#define FIRMWARE_UNLOCK_CRC       0x12344321


typedef struct{
    char sign[4];           /* 标识头，固件为：“FILE” */
    uint16_t type;          /* 类型：0（PD）、1（BMS）、2（INV） */
    uint16_t number;        /* 类型子序号 */
    /* 寄存器： */
    /* bit0-bit1（固件存储位置：0（芯片内部Flash）、1（外部SPI Flash）、2（预留）、3（预留）） */
    /* bit2（0（不需要更新）、1（需要更新）） */
    uint32_t registers;

    uint32_t address;       /* 起始地址 */
    uint32_t length;        /* 固件长度 */
    uint32_t crcValue;      /* 固件CRC16-Modbus校验值（以小端模式，存储在低16位） */

    char versionSoft[16];   /* 软件版本号 */
    char versionHard[16];   /* 硬件版本号 */

    /* 预留 */
    uint8_t reserved[64 - (sizeof(char) * (4 + 16 + 16) + sizeof(uint16_t) * 2 + sizeof(uint32_t) * 4)];
}FirmwarePortInfoType;

typedef struct{
    FirmwarePortInfoType bootloader;
    FirmwarePortInfoType bootloaderBackInside;
    FirmwarePortInfoType bootloaderBackOutside;
    FirmwarePortInfoType reserved0;

    FirmwarePortInfoType app;
    FirmwarePortInfoType appBackInside;
    FirmwarePortInfoType appBackOutside;
    FirmwarePortInfoType reserved1;
}FirmwareInfoType;



void vFirmwareInit(void);
int8_t cFirmwareWrite(void);
FirmwareInfoType *ptypeFirmwareInfoGet(void);
void vFirmwareInfoSet(uint32_t uiChannel, uint32_t uiRegisters);
void vFirmwareInfoReset(uint32_t uiChannel, uint32_t uiRegisters);

int8_t cFirmwareBootloaderUpdate(void);
int8_t cFirmwareBootloaderJump(void);

int8_t cFirmwareAPPUpdate(void);
int8_t cFirmwareAPPJump(void);



#endif
